package indi.defoliation.unknownrpg.api.attribute;

import java.util.Map;

import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.event.Listener;

/**
 * 属性.<br>
 * 我认为所有RPG物品下的lore描述都可以抽象成属性<br>
 * 所以所有属性都应该实现这个接口<br>
 * 实现并注册这个接口后，设置物品有这个属性会将这个属性写入相应的物品的nbt<br>
 * 但是并不会增加对应的lore描述<br>
 * 若要增加lore描述请看{@link indi.defoliation.unknownrpg.api.lore.loretable.item.loretable.NBTLoreTable}<br>
 * 
 * 
 * @author defoli_ation
 *
 */
public abstract class Attribute implements ConfigurationSerializable,Cloneable,Listener{
	
	
	/**
	 * 当从硬盘的配置文件载入时(yml)，会检查key，若key和方法一致.<br>
	 * 认为这个物品有这个属性,这时将会先clone后调用{@link indi.defoliation.unknownrpg.api.attribute.Attribute#deserialize}<br>
	 * 
	 * 
	 * @return 这个类在配置文件中的关键词
	 */
	public abstract String getKeyName();
	
	
	/**
	 * 在lore中展示的名字.
	 * {@link indi.defoliation.unknownrpg.api.lore.loretable.item.loretable.NBTLoreTable}应该会调用这个方法<br>
	 * 
	 * @return 在物品lore中展示的名称
	 */
	public abstract String getDisplayName();
	
	
	/**
	 * 反序列化.<br>
	 * 假若key为Attribute.value<br>
	 * 那么传入的map里将有一个key为value其值对应为在配置文件中的值.<br>
	 * 假若key为Attribute.Level.level<br>
	 * 那么传入的map里将有一个key为Level.level，其值对应为<br>
	 * 在配置文件中的值
	 * 
	 * 
	 * @param map 
	 */
	public abstract void deserialize(Map<String,Object> map);
	
	@Override
	public Attribute clone() {
		try {
			return (Attribute) super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public int hashCode() {
		return this.getKeyName().hashCode();
	}
	
	public boolean equals(Object o) {
		if(o==null&&!(o instanceof Attribute))return false;
		Attribute other = (Attribute) o;
		return this.getKeyName().equals(other.getKeyName());
	}
	
}